// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Aff_transformation_2.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Aff_transformation_2.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================


#include <include/Kernels.h>
#include <boost/python.hpp>
#include <boost/cstdint.hpp>


const char* Aff_transformation_2_doc[] ={
"The class Aff_transformation_2 represents two-dimensioanl affine transformations. \n\
The general form of an affine transformation is based on a homogeneous representation of points. \n\
Thereby all transformations can be realized by matrix multiplications.\n\
For more information see a C++ doc:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Kernel_23_ref/Class_Aff_transformation_2.html",

"\
t = Aff_transformation_2( Identity_transformation)\n\
introduces an identity transformation.\n\n\
t = Aff_transformation_2( Translation, Vector_2 v)\n\
introduces a translation by a vector v.\n\n\
t = Aff_transformation_2( Rotation,Direction_2 d,num,den = 1)\n\
approximates the rotation over the angle indicated by direction d, \n\
such that the differences between the sines and cosines of the rotation\n\
given by d and the approximating rotation are at most num/den each.\n\
Precondition: num/den > 0.\n\n\
t = Aff_transformation_2( Rotation,sine_rho,cosine_rho,hw = 1)\n\
introduces a rotation by the angle rho.\n\
Precondition: sine_rho**2 + cosine_rho**2 == hw2.\n\n\
t = Aff_transformation_2( Scaling,s,hw = 1)\n\
introduces a scaling by a scale factor s/hw.\n\n\
t = Aff_transformation_2( m00,m01,m02,m10,m11,m12,hw = 1)\n\
introduces a general affine transformation in the 3x3 matrix\n\
|m00 m01 m02|\n\
|m00 m00 m00|\n\
|0   0   hw |\n\n\
t = Aff_transformation_2( m00,m01,m10,m11,hw = 1)\n\
introduces a general linear transformation in the 3x3 matrix",

"t.transform ( Point_2 p) -> Point_2\n\n\
t.transform ( Vector_2 v) -> Vector_2\n\n\
t.transform ( Direction_2 d) -> Direction_2\n\n\
t.transform ( Line_2 l) -> Line_2",

"t.inverse () -> Aff_transformation_2\ngives the inverse transformation.",
"t.is_even () -> bool\nreturns true, if the transformation is not reflecting, i.e. \nthe determinant of the involved linear transformation is non-negative.",

"t.is_odd () -> bool\nreturns true, if the transformation is reflecting.",

"t.cartesian (int i,int j) -> m(i,j) of t\n",

"t.homogeneous (int i,int j) -> hm(i,j) of t\n",

"t.m (int i,int j) -> double\nreturns entry mij in a matrix representation in which m22 is 1.",

"t.hm (int i,int j) -> double\nreturns entry mij in some fixed matrix representation.",

"\
t( Point_2 p) -> Point_2\n\n\
t( Vector_2 v) -> Vector_2\n\n\
t( Direction_2 d) -> Direction_2\n\n\
t( Line_2 l) -> Line_2"

};

//BEGIN ================== Class Aff_transformation_2 =======================================
template<class kernel>
void Py_Aff_transformation_2()
{
	typedef typename kernel::Point_2 							Point_2;
 	typedef typename kernel::Vector_2 							Vector_2;
 	typedef typename kernel::Direction_2 						Direction_2;
 	typedef typename kernel::Line_2 						    Line_2;
	typedef typename kernel::Aff_transformation_2 				Aff_transformation_2;
	typedef typename kernel::FT 								FT;
	typedef typename kernel::RT									RT;

	using namespace boost::python;

// 	// ================== Some principals Transformations =======================================
// 
// 	class_< CGAL::Translation >("Translation","Tag class for affine transformations.",init<  >())
// 		.def(init< const CGAL::Translation& >())
// 	;
// 
//     class_< CGAL::Rotation >("Rotation", "Tag class for affine transformations.",init<  >())
//         .def(init< const CGAL::Rotation& >())
//     ;
// 
//     class_< CGAL::Scaling >("Scaling","Tag class for affine transformations.", init<  >())
//         .def(init< const CGAL::Scaling& >())
//     ;
// 
//     class_< CGAL::Reflection >("Reflection","Tag class for affine transformations." , init<>())
//         .def(init< const CGAL::Reflection& >())
//     ;
// 
//     class_< CGAL::Identity_transformation >("Identity_transformation","Tag class for affine transformations.", init<  >())
//         .def(init< const CGAL::Identity_transformation& >())
//     ;

    class_< Aff_transformation_2 >("Aff_transformation_2", Aff_transformation_2_doc[0],init<  >())
        .def(init< const Aff_transformation_2& >(Aff_transformation_2_doc[1]))
        .def(init< const CGAL::Identity_transformation >())
       	.def(init< const CGAL::Translation, const Vector_2& >())
        .def(init< const CGAL::Rotation, const Direction_2&, const FT&, optional< const FT& > >())
        .def(init< const CGAL::Rotation, const FT&, const FT&, optional< const FT& > >())
        .def(init< const CGAL::Scaling, const FT&, optional< const FT& > >())
        .def(init< const FT&, const FT&, const FT&, const FT&, const FT&, const FT&, optional< const FT& > >())
        .def(init< const FT&, const FT&, const FT&, const FT&, optional< const FT& > >())
        .def("transform", (Point_2 (Aff_transformation_2::*)(const Point_2&) const)&Aff_transformation_2::transform, Aff_transformation_2_doc[2])
        .def("transform", (Vector_2 (Aff_transformation_2::*)(const Vector_2&) const)&Aff_transformation_2::transform)
        .def("transform", (Direction_2 (Aff_transformation_2::*)(const Direction_2&) const)&Aff_transformation_2::transform)
        .def("transform", (Line_2 (Aff_transformation_2::*)(const Line_2&) const)&Aff_transformation_2::transform)
        .def("inverse", &Aff_transformation_2::inverse, Aff_transformation_2_doc[3])
        .def("is_even", &Aff_transformation_2::is_even, Aff_transformation_2_doc[4])
        .def("is_odd", &Aff_transformation_2::is_odd, Aff_transformation_2_doc[5])
        .def("cartesian", &Aff_transformation_2::cartesian, Aff_transformation_2_doc[6])
        .def("homogeneous", &Aff_transformation_2::homogeneous, Aff_transformation_2_doc[7])
        .def("m", &Aff_transformation_2::m, Aff_transformation_2_doc[8])
        .def("hm", &Aff_transformation_2::hm, Aff_transformation_2_doc[9])
        .def("__call__", (Point_2 (Aff_transformation_2::*)(const Point_2&) const)&Aff_transformation_2::operator (), Aff_transformation_2_doc[10])
        .def("__call__", (Vector_2 (Aff_transformation_2::*)(const Vector_2&) const)&Aff_transformation_2::operator ())
        .def("__call__", (Direction_2 (Aff_transformation_2::*)(const Direction_2&) const)&Aff_transformation_2::operator ())
        .def("__call__", (Line_2 (Aff_transformation_2::*)(const Line_2&) const)&Aff_transformation_2::operator ())
        .def( self * self )
    ;
}
//END ================== Class Aff_transformation_2 =======================================


void export_Aff_transformation_2()
{
	Py_Aff_transformation_2<K>();
}
